package run

import (
	"fmt"
	"go-redis/utils"
	"log"
	"time"
)

type Database struct {
	db  *Dict
	aof *AofPersistent
	rdb *RDBPersistent
	// cleanup []func(interface{}) interface{}
}

var cmd = make(chan string)
var result = make(chan string)

func NewDataBase() *Database {

	aof, _ := NewAofPersistent(utils.Cnf.AOFStrategy, cmd, result, utils.Cnf.AOFPath)
	rdb := NewRDBPersistent(utils.Cnf.RDBPath)

	d := NewDict()
	if utils.Cnf.UseAOF {
		go aof.Start()
	}
	if utils.Cnf.UseRDB {
		go func() {
			ticker := time.NewTicker(40 * time.Second)
			for {
				<-ticker.C
				utils.Log.Info("save rdb")
				rdb.CopyChan <- d.HashTable[0].Table
				utils.Log.Info(fmt.Sprintf("Used %d, Size %d", d.HashTable[0].Used, d.HashTable[0].Size))
				_ = rdb.SaveToDisk()
			}
		}()
	}

	return &Database{
		db:  d,
		aof: aof,
		rdb: rdb,
	}
}
func (receiver *Database) Set(key string, val interface{}) bool {
	if ok := receiver.db.DictAdd(key, val); !ok {
		log.Fatal("insert error")
	}
	cmd <- "set " + key + " " + fmt.Sprintf("%s", val)
	<-result
	return true
}

func (receiver *Database) Get(key string) *DictEntry {
	res := receiver.db.DictFind(key)
	cmd <- "get " + key
	<-result

	if res != nil {
		return res
	}
	return nil
}

func (receiver *Database) Del(k string) {
	receiver.db.DictDel(k)
	cmd <- "del " + k
	<-result
}

func (receiver *Database) SaveRDB() {
	receiver.rdb.CopyChan <- receiver.db.HashTable[0].Table
	_ = receiver.rdb.SaveToDisk()
}
